/**
 * 事件装饰器
 * 
 * 提供基于装饰器的事件订阅方式（适用于 Cocos Creator 组件）
 * 
 * @author AI Assistant
 * @date 2025-11-30
 * @version 1.0.0
 */

import { Component } from 'cc';
import { EventManager, globalEventManager, EventListenerOptions } from './EventManager';

/**
 * 事件监听装饰器
 * 
 * 自动在组件 onLoad 时订阅事件，onDestroy 时取消订阅
 * 
 * @param eventType 事件类型
 * @param options 监听器配置
 * 
 * @example
 * ```typescript
 * import { Component } from 'cc';
 * import { EventListener } from './EventDecorator';
 * import { GameEvent } from './EventBus';
 * 
 * export class PlayerController extends Component {
 *     @EventListener(GameEvent.PLAYER_LEVEL_UP)
 *     private onLevelUp(data: any) {
 *         console.log('玩家升级:', data);
 *     }
 * 
 *     @EventListener('customEvent', { priority: 10 })
 *     private onCustomEvent(data: any) {
 *         console.log('自定义事件:', data);
 *     }
 * }
 * ```
 */
export function EventListener(eventType: string, options?: EventListenerOptions) {
    return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
        const originalOnLoad = target.onLoad;
        const originalOnDestroy = target.onDestroy;

        // 存储取消订阅函数
        const unsubscribeKey = `__event_unsubscribe_${propertyKey}`;

        // 重写 onLoad
        target.onLoad = function (this: Component) {
            // 调用原始 onLoad
            if (originalOnLoad) {
                originalOnLoad.call(this);
            }

            // 订阅事件
            const handler = descriptor.value.bind(this);
            const unsubscribe = globalEventManager.on(
                eventType,
                handler,
                { ...options, target: this }
            );

            // 保存取消订阅函数
            (this as any)[unsubscribeKey] = unsubscribe;
        };

        // 重写 onDestroy
        target.onDestroy = function (this: Component) {
            // 取消订阅
            const unsubscribe = (this as any)[unsubscribeKey];
            if (unsubscribe) {
                unsubscribe();
                delete (this as any)[unsubscribeKey];
            }

            // 调用原始 onDestroy
            if (originalOnDestroy) {
                originalOnDestroy.call(this);
            }
        };

        return descriptor;
    };
}

/**
 * 一次性事件监听装饰器
 * 
 * @param eventType 事件类型
 * @param options 监听器配置
 * 
 * @example
 * ```typescript
 * export class GameController extends Component {
 *     @EventListenerOnce(GameEvent.GAME_START)
 *     private onGameStart(data: any) {
 *         console.log('游戏开始（只触发一次）');
 *     }
 * }
 * ```
 */
export function EventListenerOnce(eventType: string, options?: EventListenerOptions) {
    return EventListener(eventType, { ...options, once: true });
}

/**
 * 自动清理事件监听器的装饰器（用于组件类）
 * 
 * 自动在组件销毁时清理所有该组件订阅的事件
 * 
 * @example
 * ```typescript
 * @AutoCleanupEvents
 * export class MyComponent extends Component {
 *     onLoad() {
 *         // 手动订阅事件
 *         globalEventManager.on('someEvent', this.onSomeEvent, { target: this });
 *     }
 * 
 *     // 组件销毁时自动清理
 * }
 * ```
 */
export function AutoCleanupEvents(constructor: Function) {
    const originalOnDestroy = constructor.prototype.onDestroy;

    constructor.prototype.onDestroy = function (this: Component) {
        // 清理该组件的所有事件监听器
        globalEventManager.offByTarget(this);

        // 调用原始 onDestroy
        if (originalOnDestroy) {
            originalOnDestroy.call(this);
        }
    };
}

